Permissions on iOS & Android with React Native
Mobile Permissions in React Native: A Setup Guide
Mobile permissions are essential security features that give users control over which hardware and software components an app can access. This guide explains how to implement permissions in React Native using the react-native-permissions
library.
Understanding Mobile Permissions
Mobile apps need explicit user permission to access device resources like:
- Camera
- Photo library
- Microphone
- Location services
Each platform handles permissions differently:
iOS
Permissions are defined in the Info.plist
Example for camera access:
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to take photos</string>
Android
Permissions are defined in the AndroidManifest.xml
Example for camera access:
<uses-permission android:name="android.permission.CAMERA" />
Step 1: Install react-native-permissions & pods
npm install react-native-permissions && npx pod-install
Note - you may need to run react-native link react-native-permissions
if using React Native < .60 where auto-linking is not the default behavior.
Step 2: Edit the necessary files
Info.plist
Add the following to your Info.plist
:
<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) would like to access your photo library</string>
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your microphone</string>
AndroidManifest.xml
Add the following to your AndroidManifest.xml
:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Podfile
Add the following to your Podfile
:
pod 'Permission-Camera', :path => '../node_modules/react-native-permissions/ios/Camera/Permission-Camera.podspec'
pod 'Permission-PhotoLibrary', :path => '../node_modules/react-native-permissions/ios/PhotoLibrary/Permission-PhotoLibrary.podspec'
pod 'Permission-MediaLibrary', :path => '../node_modules/react-native-permissions/ios/MediaLibrary/Permission-MediaLibrary.podspec'
pod 'Permission-PhotoLibraryAddOnly', :path => '../node_modules/react-native-permissions/ios/PhotoLibraryAddOnly/Permission-PhotoLibraryAddOnly.podspec'
package.json
Add the following to your package.json
:
"reactNativePermissionsIOS": [
"MediaLibrary",
"PhotoLibrary",
"Camera",
"PhotoLibraryAddOnly"
],
Step 3: Create a usePermission hook
Create a custom React hook named usePermission
with the following:
import { useState, useEffect } from "react";
import { Platform } from "react-native";
import {
PERMISSIONS,
checkMultiple,
requestMultiple,
} from "react-native-permissions";
const usePermissions = () => {
const [cameraStatus, setCameraStatus] = useState("");
const [photoLibraryStatus, setPhotoLibraryStatus] = useState("");
const [mediaLibraryStatus, setMediaLibraryStatus] = useState("");
const [photoLibraryAddOnlyStatus, setPhotoLibraryAddOnlyStatus] =
useState("");
useEffect(() => {
const requestPermissions = async () => {
try {
const permissions =
Platform.OS === "android"
? [
PERMISSIONS.ANDROID.CAMERA,
PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE,
PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
]
: [
PERMISSIONS.IOS.CAMERA,
PERMISSIONS.IOS.PHOTO_LIBRARY,
PERMISSIONS.IOS.MEDIA_LIBRARY,
PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY,
];
const statuses = await checkMultiple(permissions);
const shouldRequest = Object.values(statuses).some(
(status) => status === "blocked" || status === "denied"
);
if (shouldRequest) {
const results = await requestMultiple(permissions);
setCameraStatus(results[permissions[0]]);
setPhotoLibraryStatus(results[permissions[1]]);
setMediaLibraryStatus(results[permissions[2]]);
setPhotoLibraryAddOnlyStatus(results[permissions[3]]);
} else {
setCameraStatus(statuses[permissions[0]]);
setPhotoLibraryStatus(statuses[permissions[1]]);
setMediaLibraryStatus(statuses[permissions[2]]);
setPhotoLibraryAddOnlyStatus(statuses[permissions[3]]);
}
} catch (error) {
console.log(error);
}
};
requestPermissions();
}, []);
return {
cameraStatus,
photoLibraryStatus,
mediaLibraryStatus,
photoLibraryAddOnlyStatus,
};
};
export default usePermissions;
Step 4 - Use in the root of your app (or where you need it)
function App(): JSX.Element {
const {
cameraStatus,
photoLibraryStatus,
mediaLibraryStatus,
photoLibraryAddOnlyStatus,
} = usePermissions();
console.log({
permissions: {
cameraStatus,
photoLibraryStatus,
mediaLibraryStatus,
photoLibraryAddOnlyStatus,
},
});
return (...)
Conclusion
I hope this guide helped! Please remember to do the following if you're running into build errors:
- Remove and reinstall
node_modules
- Remove stale build crap
rm -rf path/to/ios/build
& rebuild with Xcode/Android Studio - Clear pod cache
pod cache clean --all
- Reinstall pods
npx pod-install
- Check syntax of Info.plist & Android.xml